package vip

import (
	"context"
	"fmt"
	"service/api/api"
	model "service/model/crm_order"
	mCache "service/model/hr_cache"
	"service/model/mod"
	"time"

	"gitee.com/cloudapex/protos/comm/pb"
	gpb "gitee.com/cloudapex/protos/crm_order/pb"
	gupb "gitee.com/cloudapex/protos/hr_cache/pb"
	"gitee.com/cloudapex/ulern/htp"
	"gitee.com/cloudapex/ulern/util"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
	"github.com/gin-gonic/gin"
)

/*
 * 描述: 添加金卡下单
 * 路由: /notify/adminInnmsgAdd
 * 方法: POST
 *********************************************************************/
type AddVipCardReq struct {
	Phone      string          `form:"phone" json:"phone" binding:"required"`           // 手机号
	OrderType  int64           `form:"orderType" json:"orderType" binding:"required"`   // 开课订单类型 默认1  内部员工
	TotalPrice int64           `form:"totalPrice" json:"totalPrice" binding:"required"` // 实际支付价格
	Notes      string          `form:"notes" json:"notes"`                              // 订单通用备注
	InfoList   []*OrderInfoReq `form:"infoList" json:"infoList"`                        //网课详情
}

// 说明：金卡订单网课详情 入参
type OrderInfoReq struct {
	ProjectId   int64  `form:"projectId" json:"projectId" binding:"omitempty"`     //项目ID
	ProjectName string `form:"projectName" json:"projectName" binding:"omitempty"` //项目名称
	ClassId     int64  `form:"classId" json:"classId" binding:"omitempty"`         //班型ID
	ClassName   string `form:"className" json:"className" binding:"omitempty"`     //班型名称
	Price       int64  `form:"price" json:"price" binding:"omitempty"`             //网课价格
}

func (this *AddVipCardReq) Handle(c *gin.Context, ctx context.Context) htp.Response {
	jwtUser := mod.CurrUser(c)
	if this.InfoList == nil || len(this.InfoList) == 0 {
		return htp.RespParamErr("infoList参数不能为空", nil)

	}
	//  赋值
	var infos []*gpb.CrmGoldenOrderInfoReq
	for _, it := range this.InfoList {
		infos = append(infos, &gpb.CrmGoldenOrderInfoReq{
			ProjectId:   it.ProjectId,
			ProjectName: it.ProjectName,
			ClassId:     it.ClassId,
			ClassName:   it.ClassName,
			Price:       it.Price,
			BillType:    1, //网课类型 1网课
		})
	}
	in := &gpb.CrmGoldenOrderCreateReq{
		CommpId:    jwtUser.CId,
		Phone:      this.Phone,
		OrderType:  this.OrderType,
		TotalPrice: this.TotalPrice,
		Notes:      this.Notes,
		InfoList:   infos,
		UserId:     jwtUser.UId,
	}

	_, err := model.Order.CrmGoldenOrderCreate(ctx, in)
	if err != nil {
		return htp.RespModelErr("", err)
	}
	return htp.RespOK("", "下单成功")
}

/*
 * 描述: 金卡列表
 * 路由: /vip/vipCardList
 * 方法: POST
 *********************************************************************/
type VipCardList struct {
	mod.SortFinder
	mod.PageFinder
	Phone     string `form:"phone" json:"phone" binding:"omitempty"`         //手机号
	BillNo    string `form:"billNo" json:"billNo" binding:"omitempty"`       //订单号
	UserId    int64  `form:"userId" json:"userId" binding:"omitempty"`       //下单坐席
	IsCrm     int64  `form:"isCrm" json:"isCrm" binding:"omitempty"`         //是否为crm端 0否 1：是
	ProjectId int64  `form:"projectId" json:"projectId" binding:"omitempty"` //项目ID
	State     int64  `form:"state" json:"state" binding:"omitempty"`         //订单状态
}

// 说明：金卡订单 出参
type VipCardListRes struct {
	CommpId    int64           `form:"commpId" json:"commpId"`       // 公司ID
	Phone      string          `form:"phone" json:"phone"`           // 手机号
	OrderType  int64           `form:"orderType" json:"orderType"`   // 开课订单类型 默认1  内部员工
	ShowId     uint64          `form:"showId" json:"showId"`         // 所属组织ID
	RoleId     int64           `form:"roleId" json:"roleId"`         // 所属角色ID
	TotalPrice int64           `form:"totalPrice" json:"totalPrice"` // 实际支付价格
	Notes      string          `form:"notes" json:"notes"`           // 订单通用备注
	OrderId    int64           `form:"orderId" json:"orderId"`       // 订单ID (主键id)
	BillNo     string          `form:"billNo" json:"billNo"`         // 账单号
	PayAt      int64           `form:"payAt" json:"payAt"`           // 审核时间
	AdminId    int64           `form:"adminId" json:"adminId"`       // 审核人
	CreateAt   int64           `form:"createAt" json:"createAt"`     //创建时间
	Reason     string          `form:"reason" json:"reason"`         //订单驳回原因
	ReasonAt   int64           `form:"reasonAt" json:"reasonAt"`     //订单驳回时间
	Status     int64           `form:"status" json:"status"`         //订单状态(1.未审核2、已审核3、已取消 4、已驳回5、已关课)
	Details    []*OrderInfoRes `form:"details" json:"details"`       //订单下的网课详情
	UserId     int64           `form:"userId" json:"userId"`         //下单坐席
	CloseAt    int64           `form:"closeAt" json:"closeAt"`       //关课时间
	CancelAt   int64           `form:"cancelAt" json:"cancelAt"`     //取消时间

	UserName  string `form:"userName" json:"userName"`   //下单人名
	AdminName string `form:"adminName" json:"adminName"` // 审核人
}

type OrderInfoRes struct {
	OrderId     int64  `form:"orderId" json:"orderId"`          //订单ID
	ProjectId   int64  `form:"projectId" json:"projectId"`      //项目ID
	ProjectName string `form:"projectNa	me" json:"projectName"` //项目名称
	ClassId     int64  `form:"classId" json:"classId"`          //班型ID
	ClassName   string `form:"className" json:"className"`      //班型名称
	Price       int64  `form:"price" json:"price"`              //网课价格
}

func (this *VipCardList) Handle(c *gin.Context, ctx context.Context) htp.Response {
	jwtUser := mod.CurrUser(c)
	if this.IsCrm == 1 {
		this.UserId = jwtUser.UId
	}
	//传参
	compyListreq := &gpb.CrmGoldenOrderListReq{
		CommpId: jwtUser.CId,
		Pager: &pb.PageResponse{
			Page:  int64(this.Page),
			Count: int64(this.Pnum),
			Order: int64(this.Order),
			Orule: int64(this.Orule + 1),
		},
		BillNo:    this.BillNo,
		Phone:     this.Phone,
		UserId:    this.UserId,
		ProjectId: this.ProjectId,
		State:     this.State,
		OrderBgn:  this.Bgn,
		OrderEnd:  this.End,
	}

	list, err := model.Order.CrmGoldenOrderList(ctx, compyListreq)
	if list == nil || nil != err {
		return htp.RespParamErr("", err)
	}

	//映射
	items := []*VipCardListRes{}
	if err := util.Convert(&items, list.Data); err != nil {
		return htp.RespConvertErr("", err)
	}

	if err != nil {
		return htp.RespModelErr("", err)
	}

	//人名赋值
	setUserName(items, err, ctx, jwtUser)

	return htp.RespOK("", &struct {
		Total int64       `json:"total"`
		List  interface{} `json:"list"`
	}{list.Pager.Total, items})

}

/*
 * 描述: 金卡列表导出
 * 路由: /vip/vipCardList
 * 方法: POST
 *********************************************************************/
type ExportVipCard struct {
	mod.SortFinder
	mod.PageFinder
	Phone     string `form:"phone" json:"phone" binding:"omitempty"`         //手机号
	BillNo    string `form:"billNo" json:"billNo" binding:"omitempty"`       //订单号
	UserId    int64  `form:"userId" json:"userId" binding:"omitempty"`       //下单坐席
	ProjectId int64  `form:"projectId" json:"projectId" binding:"omitempty"` //项目ID
	State     int64  `form:"state" json:"state" binding:"omitempty"`         //订单状态
}

func (this *ExportVipCard) Handle(c *gin.Context, ctx context.Context) htp.Response {
	jwtUser := mod.CurrUser(c)
	//传参
	compyListreq := &gpb.CrmGoldenOrderListReq{
		CommpId: jwtUser.CId,
		Pager: &pb.PageResponse{
			Page: int64(this.Page),
			//Count: int64(this.Pnum),
			Count: 100000,
			Order: int64(this.Order),
			Orule: int64(this.Orule + 1),
		},
		BillNo:    this.BillNo,
		Phone:     this.Phone,
		UserId:    this.UserId,
		ProjectId: this.ProjectId,
		State:     this.State,
		OrderBgn:  this.Bgn,
		OrderEnd:  this.End,
	}

	list, err := model.Order.CrmGoldenOrderList(ctx, compyListreq)
	if list == nil || nil != err {
		return htp.RespParamErr("", err)
	}

	//映射
	items := []*VipCardListRes{}
	if err := util.Convert(&items, list.Data); err != nil {
		return htp.RespConvertErr("", err)
	}

	if err != nil {
		return htp.RespModelErr("", err)
	}

	//人名赋值
	setUserName(items, err, ctx, jwtUser)
	this.HandleVipCardExportXls(c, ctx, items)
	return htp.RespOK("", "")

}

/*
 * 描述: 金卡订单状态更改
 * 路由: /vip/updateState
 * 方法: POST
 *********************************************************************/
type UpdateState struct {
	OrderId  int64  `form:"orderId" json:"orderId" binding:"required"`             //订单ID
	Status   int64  `form:"status" json:"status" binding:"required,min=1,max=100"` //订单状态(1.未审核2、已审核3、已取消 4、已驳回5、已关课)
	Notes    string `form:"notes" json:"notes"`                                    //驳回备注
	ReasonAt int64  `form:"reasonAt" json:"reasonAt"`                              //驳回时间
	CancelAt int64  `form:"cancelAt" json:"cancelAt"`                              //取消时间
	CloseAt  int64  `form:"closeAt" json:"closeAt"`                                //关课时间
	PayAt    int64  `form:"payAt" json:"payAt"`                                    //审核时间
}

func (this *UpdateState) Handle(c *gin.Context, ctx context.Context) htp.Response {
	req := &gpb.CrmGoldenOrderBhReq{
		OrderId:  this.OrderId,
		Status:   this.Status,
		Reason:   this.Notes,
		ReasonAt: this.ReasonAt,
		CancelAt: this.CancelAt,
		CloseAt:  this.CloseAt,
		PayAt:    this.PayAt,
	}
	_, err := model.Order.CrmGoldenOrderStatus(ctx, req)
	// 通过审核，进行开课
	if this.Status == 2 || this.Status == 5 {
		req := &gpb.CrmGoldenOrderGetReq{
			OrderId: this.OrderId,
		}
		orderInfo, err := model.Order.CrmGoldenOrderGet(ctx, req)
		if err != nil || orderInfo == nil || orderInfo.Details == nil || len(orderInfo.Details) == 0 {
			msg := "开课失败"
			if this.Status == 5 {
				msg = "此用户已经关闭订单"
			}

			return htp.RespModelErr(msg, err)
		}
		userClassIdList := make([]int64, 0)
		for _, o := range orderInfo.Details {
			userClassIdList = append(userClassIdList, o.ClassId)
		}

		if this.Status == 2 {
			api.ClassOpen(c, orderInfo.Phone, 0, userClassIdList)
		}
		if this.Status == 5 {

			api.ClassClose(c, orderInfo.Phone, userClassIdList)
		}

	}

	if err != nil {
		return htp.RespModelErr("", err)
	}
	return htp.RespOK("", "")
}

/*************************************************提取方法*********************************************************/
func setUserName(items []*VipCardListRes, err error, ctx context.Context, jwtUser *mod.CustomClaims) {
	ids := make([]int64, 0)
	for _, f := range items {
		bo := false
		if len(ids) > 0 {
			for _, id := range ids {
				if id == f.UserId {
					bo = true
				}
			}
		}
		if !bo && f.UserId > 0 {
			ids = append(ids, f.UserId)
		}
		//审核人
		bo = false
		if len(ids) > 0 {
			for _, id := range ids {
				if id == f.AdminId {
					bo = true
				}
			}
		}
		if !bo && f.AdminId > 0 {
			ids = append(ids, f.AdminId)
		}

	}
	resNameList, err := mCache.UserCacheServer.UserNameList(ctx, &gupb.UserLoginReqIdsReq{
		CId: jwtUser.CId,
		Ids: ids,
	})
	if err == nil && resNameList != nil && len(resNameList.NameList) > 0 {
		for i, _ := range items {
			com := items[i]

			for _, resname := range resNameList.NameList {
				if resname.Id == com.UserId {
					com.UserName = resname.Name
				}
				if resname.Id == com.AdminId {
					com.AdminName = resname.Name
				}

			}

		}
	}
}

func (this *ExportVipCard) HandleVipCardExportXls(c *gin.Context, ctx context.Context, items []*VipCardListRes) htp.Response {
	if len(items) == 0 {
		return htp.RespErr(1, "没有可导出的数据", nil)
	}

	xlsx := excelize.NewFile()
	_ = xlsx.SetSheetRow("Sheet1", "A1", &[]interface{}{
		"手机号", "订单号", "开课类型", "下单金额", "下单时间", "取消时间",
		"审核时间", "驳回时间", "关课时间", "驳回原因", "下单坐席", "订单状态", "订单备注", "订单内容",
	})

	for n, it := range items {
		var strState = []string{"未审核", "已审核", "已取消", "已驳回", "已关课", "未知状态"}
		detail := ""

		if it.Status < 1 && it.Status > 5 {
			it.Status = 6
		}
		for _, d := range it.Details {
			detail += d.ProjectName + "-" + d.ClassName + ","
		}
		detail = mod.TrimLastChar(detail)
		_ = xlsx.SetSheetRow("Sheet1", fmt.Sprintf("A%d", n+2), &[]interface{}{
			it.Phone,
			it.BillNo,
			"内部员工开课",
			it.TotalPrice / 100,
			mod.GetTimestr(it.CreateAt),
			mod.GetTimestr(it.CancelAt), //  取消时间
			mod.GetTimestr(it.PayAt),    //  审核时间
			mod.GetTimestr(it.ReasonAt), //  驳回时间
			mod.GetTimestr(it.CloseAt),  //  关课时间
			it.Reason,
			it.UserName,
			strState[(it.Status - 1)],
			it.Notes,
			detail,
		})
	}

	buf, err := xlsx.WriteToBuffer()
	if err != nil {
		return htp.RespErr(2, "导出异常", err)
	}
	return htp.RespFileData(c, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
		fmt.Sprintf("vipCardList[%v].xlsx", util.TimeFormat_(time.Now())), buf.Bytes())
}
